package org.frankkie.parcdroidprj;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author frankkie
 */
public class OverlayRoute extends Overlay {

  public static boolean routeLatenZien = false;
  public static int deRotatie = 15;

  /**
   * @return the routeLatenZien
   */
  public static boolean isRouteLatenZien() {
    return routeLatenZien;
  }

  /**
   * @param aRouteLatenZien the routeLatenZien to set
   */
  public static void setRouteLatenZien(boolean aRouteLatenZien) {
    if (aRouteLatenZien == false) {
      System.out.println("OverlayRoute.setRouteLatenZien: Punten zwart-maken :P");
      //Alle Punten Zwart maken
      ArrayList<OverlayPunt> allePunten = OverlayDinges.getGpsPlekken();
      for (int b = 0; b < allePunten.size(); b++) {
        allePunten.get(b).setKleur(Color.BLACK);
        allePunten.get(b).setGrootte(OverlayPunt.standaardGrootte);
      }
    }
    //Repainten
    MainActivity.mapController.scrollBy(-1, -1);
    MainActivity.mapController.scrollBy(1, 1);

    routeLatenZien = aRouteLatenZien;
  }
  Path mPath = new Path();
  Paint paint = new Paint();
  public MainActivity main;
  public SensorManager mSensorManager;
  public Sensor compassSensor;
  //public static double deAfstandDieJeVanHetPuntMoetZijnOmNaarHetVolgendePuntTeGaan = 0.001;
  public static double deAfstandDieJeVanHetPuntMoetZijnOmNaarHetVolgendePuntTeGaan = 15.0; //in meters
  public float[] compassValues = new float[3];
  double afstandTotPunt;
  public final SensorEventListener compassListener = new SensorEventListener() {

    public void onSensorChanged(SensorEvent arg1) {
      SensorEvent arg0 = arg1;
      if (arg0.sensor.getType() == compassSensor.getType()) {
        //System.out.println("sensorChanged-compass (" + arg0.values[0] + ", " + arg0.values[1] + ", " + arg0.values[2] + ")");
        compassValues = arg0.values;
      }

      //if (mView != null) {
      //    mView.invalidate();
      //}

      proberenTeRepainten();

      //throw new UnsupportedOperationException("Not supported yet.");
      arg0 = null;
      arg1 = null;
    }

    public void onAccuracyChanged(Sensor arg0, int arg1) {
      //throw new UnsupportedOperationException("Not supported yet.");
    }
  };

  public void proberenTeRepainten() {
    //Proberen om meteen te repainten
    MainActivity.mapController.scrollBy(1, 1);
    MainActivity.mapController.scrollBy(-1, -1);
  }

  public static ArrayList<RouteMelding> maakRouteMeldingenLijst(List<OverlayPunt> l) {
    ArrayList<RouteMelding> ans = new ArrayList<RouteMelding>();
    for (int a = 0; a < l.size(); a++) {
      ans.add(new RouteMelding(a, -1, l.get(a), ""));
      //////PRINT
      System.out.println(new RouteMelding(a, -1, l.get(a), ""));
      //////EIND PRINT
    }
    return ans;
  }

  public OverlayRoute(MainActivity main) {
    this.main = main;

    //COMPASS
    mSensorManager = (SensorManager) main.getSystemService(Context.SENSOR_SERVICE);
    compassSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);



    /*
    mPath.moveTo(0, -25);
    mPath.lineTo(-10, 30);
    mPath.lineTo(0, 25);
    mPath.lineTo(10, 30);
    mPath.close();
    //
    mPath.moveTo(0, -50);
    mPath.lineTo(-20, 60);
    mPath.lineTo(0, 50);
    mPath.lineTo(20, 60);
    mPath.close();
     */
    mPath.moveTo(0, -100);
    mPath.lineTo(-40, 120);
    mPath.lineTo(0, 100);
    mPath.lineTo(40, 120);
    mPath.close();
  }

  public void deResumeVanOverlayRoute() {
    System.out.println("deResumeVanOverlayRoute");
    //super.onResume();

    //COMPASS
    mSensorManager.registerListener(compassListener, compassSensor, SensorManager.SENSOR_DELAY_NORMAL);
  }

  public void deStopVanOverlayRoute() {
    mSensorManager.unregisterListener(compassListener);
  }

  public void jeKanNaarHetVolgendePuntMeldingGeven() {
    main.geluidAfspelen();
    main.startVibrate(2 * 1000); //2sec
  }

  public void lokatieIsVeranderd() {
    System.out.println("OverlayRoute.lokatieIsVeranderd");

    //Pijl-richting updaten
    ArrayList<RouteMelding> deLijst = MainActivity.deJuisteRoute;
    System.out.println("deLijst.size() = " + deLijst.size());
    //p is het volgende punt waar je heen moet

    System.out.println("OverlayRoute.lokatieIsVeranderd: Punten kleuren (1) :P");
    //Alle Punten Zwart maken
    ArrayList<OverlayPunt> allePunten = OverlayDinges.getGpsPlekken();
    for (int b = 0; b < allePunten.size(); b++) {
      allePunten.get(b).setKleur(Color.BLACK);
      allePunten.get(b).setGrootte(OverlayPunt.standaardGrootte);
    }

    OverlayPunt p = null;
//    deRotatie += 10; //Heb niet veel zin he XD
//    if (MainActivity.waarZijnDeOuders.equalsIgnoreCase("StoomCarousel")) {
//      p = OverlayDinges.getGpsPlekken().get(14);
//    } else if (MainActivity.waarZijnDeOuders.equalsIgnoreCase("Hoofdingang")) {
//      p = OverlayDinges.getGpsPlekken().get(2);
//    }

    if (deLijst.size() == 0) {

      if (isRouteLatenZien()) {
        doeEindeMelding();
        setRouteLatenZien(false);
      }
      return;
    } else {
      p = deLijst.get(0).punt;
    }

    //Checken of je naar het volgende Punt kan gaan
//    double afstandTotPunt = mijnPoint2D.distance(MainActivity.location.getLongitude(),
//            MainActivity.location.getLatitude(),
//            0.0 + p.getGeoPoint().getLongitudeE6() / 1E6,
//            0.0 + p.getGeoPoint().getLatitudeE6() / 1E6);
//    System.out.println("DINGEN: " + MainActivity.location.getLongitude() + " //\n " +
//            MainActivity.location.getLatitude() + " //\n " +
//            0.0 + p.getGeoPoint().getLongitudeE6() / 1E6 + " //\n " +
//            0.0 + p.getGeoPoint().getLatitudeE6() / 1E6);
    //float[] aa = new float[3];

    ///////////////////////////////////////////////////////////////
    //HET VOLGENDE STUKJE KOMT 2x
    //IS NODIG, OMDAT JE ANDERS OP DE VOLGENDE GPS_FIX MOET W8EN
//    afstandTotPunt = gps2m(MainActivity.location.getLongitude(),
//            MainActivity.location.getLatitude(),
//            0.0 + p.getGeoPoint().getLongitudeE6() / 1E6,
//            0.0 + p.getGeoPoint().getLatitudeE6() / 1E6);
    GeoPoint geoPointVanDeGPSLokatie = OverlayDing.getPoint(MainActivity.location.getLatitude(), MainActivity.location.getLongitude());
    afstandTotPunt = DistanceCalculator.CalculationByDistance(geoPointVanDeGPSLokatie, p.getGeoPoint());
    System.out.println("(1!!)De afstand tussen GPS en p = " + afstandTotPunt + " meter");
    if (afstandTotPunt < deAfstandDieJeVanHetPuntMoetZijnOmNaarHetVolgendePuntTeGaan) {
      deLijst.remove(0);
      if (deLijst.size() == 0) {
        if (isRouteLatenZien()) {
          doeEindeMelding();
          setRouteLatenZien(false);
        }
        return;
      } else {
        p = deLijst.get(0).punt;
        jeKanNaarHetVolgendePuntMeldingGeven();
      }
    }
    //2e KEER
//    afstandTotPunt = gps2m(MainActivity.location.getLongitude(),
//            MainActivity.location.getLatitude(),
//            0.0 + p.getGeoPoint().getLongitudeE6() / 1E6,
//            0.0 + p.getGeoPoint().getLatitudeE6() / 1E6);
//    System.out.println("(1)De afstand tussen GPS en p = " + afstandTotPunt + " meter");
//    if (afstandTotPunt < deAfstandDieJeVanHetPuntMoetZijnOmNaarHetVolgendePuntTeGaan) {
//      deLijst.remove(0);
//      if (deLijst.size() == 0) {
//        if (routeLatenZien) {
//          doeEindeMelding();
//          routeLatenZien = false;
//        }
//        return;
//      } else {
//        p = deLijst.get(0).punt;
//        jeKanNaarHetVolgendePuntMeldingGeven();
//      }
//    }
    ////////////////////////////////////////////////////////////////

    ////
//    if (deLijst.size() == 0) {
//        if (routeLatenZien) {
//          doeEindeMelding();
//          routeLatenZien = false;
//          return;
//        }
//    }
    ////

    System.out.println("OverlayRoute.lokatieIsVeranderd: Punten kleuren (2) :P");
    //Alle Punten Zwart maken
//    ArrayList<OverlayPunt> allePunten = OverlayDinges.getGpsPlekken();
//    for (int b = 0; b < allePunten.size(); b++) {
//      allePunten.get(b).setKleur(Color.BLACK);
//      allePunten.get(b).setGrootte(OverlayPunt.standaardGrootte);
//    }

    //PUNTEN ALLEEN KLEUREN ALS ROUTEOVERLAY AAN STAAT
    if (isRouteLatenZien()) {
      //Punten waar je langs komt blauw maken
      for (int a = 0; a < deLijst.size(); a++) {
        //deLijst.get(a).punt.setGrootte(6);
        deLijst.get(a).punt.setKleur(Color.BLUE);
        deLijst.get(a).punt.setGrootte(5);
      }

      //Eerst-volgende punt groen maken
      p.setKleur(Color.GREEN);

      //Laatste Punt rood
      deLijst.get(deLijst.size() - 1).punt.setKleur(Color.RED);
    }
    //Direction uitrekenen.
    //MainActivity.location
    /*
    double afstandMijnPuntTotDoelpunt = mijnPoint2D.distance(MainActivity.location.getLongitude(),
    MainActivity.location.getLatitude(),0.0+ p.geoPoint.getLongitudeE6() / 1E6,0.0+ p.geoPoint.getLatitudeE6() / 1E6);
    double deltaX = 0;
    double deltaY = 0;
    if (p.geoPoint.getLongitudeE6() / 1E6 > MainActivity.location.getLongitude()) {
    deltaX = (p.geoPoint.getLongitudeE6() / 1E6) - MainActivity.location.getLongitude();
    } else {
    deltaX = MainActivity.location.getLongitude() - (p.geoPoint.getLongitudeE6() / 1E6);
    }
    if (p.geoPoint.getLatitudeE6() / 1E6 > MainActivity.location.getLatitude()) {
    deltaY = (p.geoPoint.getLatitudeE6() / 1E6) - MainActivity.location.getLatitude();
    } else {
    deltaY = MainActivity.location.getLatitude() - (p.geoPoint.getLatitudeE6() / 1E6);
    }
    double coSinusOfZo = Math.acos(deltaX / afstandMijnPuntTotDoelpunt) * (180/Math.PI);
    deRotatie = (int) coSinusOfZo;
     */
    ///////////
    //point_direction(x1,y1,x2,y2){ return dir=radtodeg(atan2(y2-y1,x2-x1));}
    //radtodeg(angle_radians) {return angle_degrees = angle_radians * 180 / pi;}
    ///////////
    System.out.println("x1=" + MainActivity.location.getLongitude() + " y1=" +
            MainActivity.location.getLatitude() + " x2=" +
            (0.0 + p.getGeoPoint().getLongitudeE6() / 1E6) + " y2=" +
            (0.0 + p.getGeoPoint().getLatitudeE6() / 1E6));
    deRotatie = (int) point_direction(
            MainActivity.location.getLongitude(),
            MainActivity.location.getLatitude(),
            0.0 + p.getGeoPoint().getLongitudeE6() / 1E6,
            0.0 + p.getGeoPoint().getLatitudeE6() / 1E6);

    //Je hoeft hier niet te repainten,
    //dat doet MainActivity.deLokatieIsVeranderd() al.
  }

//  public double gps2m(float lat_a, float lng_a, float lat_b, float lng_b) {
//    float pk = (float) (180 / 3.14169);
//
//    float a1 = lat_a / pk;
//    float a2 = lng_a / pk;
//    float b1 = lat_b / pk;
//    float b2 = lng_b / pk;
//
//    float t1 = FloatMath.cos(a1) * FloatMath.cos(a2) * FloatMath.cos(b1) * FloatMath.cos(b2);
//    float t2 = FloatMath.cos(a1) * FloatMath.sin(a2) * FloatMath.cos(b1) * FloatMath.sin(b2);
//    float t3 = FloatMath.sin(a1) * FloatMath.sin(b1);
//    double tt = Math.acos(t1 + t2 + t3);
//
//    return 6366000 * tt;
//  }
//
//  public double gps2m(double lat_a, double lng_a, double lat_b, double lng_b) {
//    double pk = (double) (180.0 / Math.PI);
//
//    double a1 = lat_a / pk;
//    double a2 = lng_a / pk;
//    double b1 = lat_b / pk;
//    double b2 = lng_b / pk;
//
//    double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
//    double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
//    double t3 = Math.sin(a1) * Math.sin(b1);
//    double tt = Math.acos(t1 + t2 + t3);
//
//    return (6366000*tt);
//    //return (6366000 * tt) / 10.0;
//  }
  public static double point_direction(double x1, double y1, double x2, double y2) {
    return radtodeg(Math.atan2(y2 - y1, x2 - x1));
  }

  public static double radtodeg(double angle_radians) {
    double angle_degrees = angle_radians * 180 / Math.PI;
    return angle_degrees;
  }

  public void doeEindeMelding() {
    //Toast.makeText(main.getApplicationContext(), "EINDPUNT BEREIKT !", Toast.LENGTH_LONG).show();

    ////////
    LayoutInflater inflater = main.getLayoutInflater();
    View layout = inflater.inflate(R.layout.toast_layout,
            (ViewGroup) main.findViewById(R.id.toast_layout_root));

    ImageView image = (ImageView) layout.findViewById(R.id.image);
    image.setImageResource(R.drawable.androidmarker);
    TextView text = (TextView) layout.findViewById(R.id.text);
    text.setTextColor(Color.RED);
    text.setTextSize(24);
    text.setText("Eindpunt is bereikt !!");

    Toast toast = new Toast(main.getApplicationContext());
    toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
    toast.setDuration(Toast.LENGTH_LONG);
    toast.setView(layout);
    toast.show();
    ///////
  }

  @Override
  public void draw(Canvas canvas, MapView arg1, boolean arg2) {
    if (isRouteLatenZien()) {

      ////
      if (MainActivity.deJuisteRoute.size() == 0) {
        if (isRouteLatenZien()) {
          doeEindeMelding();
          setRouteLatenZien(false);
          return;
        }
      }
      ////

      paint.setTextAlign(Paint.Align.LEFT);
      paint.setFakeBoldText(true);
      paint.setAntiAlias(true);

      //Tekst
      paint.setARGB(100, 0, 0, 0);
      canvas.drawRect(0, 0, 200, 80, paint);
      paint.setColor(Color.BLUE);
      canvas.drawText("Blauwe Pijl: Het Noorden", 5, 15, paint);
      paint.setColor(Color.RED);
      canvas.drawText("Rode Pijl: Waar Je Heen Moet", 5, 30, paint);
      paint.setColor(Color.GREEN);
      canvas.drawText("aantal punten nog: " + MainActivity.deJuisteRoute.size(), 5, 45, paint);
      canvas.drawText("Afstand tot volgende punt: " + significant(afstandTotPunt, 2), 5, 60, paint);
      canvas.drawText("Eindpunt: " + MainActivity.waarZijnDeOuders, 5, 75, paint);

      //Grote Cirkel
      //paint.setARGB(40, 0, 0, 0);
      paint.setARGB(20, 0, 0, 0);
      canvas.drawCircle(160, 220, 150, paint);

      //Blauwe Pijl (Het Noorden)
      paint.setARGB(30, 0, 0, 255);
      paint.setStyle(Paint.Style.FILL);
      canvas.translate(160, 220);
      canvas.rotate(-compassValues[0]);
      canvas.drawPath(mPath, paint);
      canvas.rotate(compassValues[0]);
      canvas.translate(-160, -220);

      //Rode Pijl (Die Kant Op)
      //paint.setColor(Color.RED);
      paint.setARGB(150, 255, 0, 0);
      paint.setStyle(Paint.Style.FILL);
      canvas.translate(160, 220);
      //canvas.rotate(deRotatie);
      canvas.rotate(-compassValues[0] - deRotatie + 90);
      canvas.drawPath(mPath, paint);
      //canvas.rotate(-deRotatie);
      canvas.rotate(compassValues[0] + deRotatie - 90);
      canvas.translate(-160, -220);

      //Kleine Cirkel
      paint.setColor(Color.BLACK);
      canvas.drawCircle(160, 220, 5, paint);
    }
  }

  public static double significant(double hetGetal, int aantalAchterDeKomma) {
    //double ans = hetGetal;
    String hetGetalAlsString = Double.toString(hetGetal);
    String[] deDelen = hetGetalAlsString.split("\\.");
    int hetWerkelijkeAantalAchterDeKomma = aantalAchterDeKomma - 1;
    if (deDelen[1].length() < hetWerkelijkeAantalAchterDeKomma - 1) {
      hetWerkelijkeAantalAchterDeKomma = deDelen[0].length() - 1;
    }
    String deKoekjes = deDelen[0] + "." + deDelen[1].substring(0, hetWerkelijkeAantalAchterDeKomma);
    //return ans;
    return Double.parseDouble(deKoekjes);
  }
}
